/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package pl.tewi.junit.annotations.processors;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.junit.runner.RunWith;
import pl.tewi.annotations.processors.AnnotationProcessor;
import pl.tewi.contexts.ApplicationServerContext;
import pl.tewi.exceptions.AnnotationProcessingException;
import pl.tewi.exceptions.FileOrDirectoryException;
import pl.tewi.exceptions.GeneralFrameworkException;
import pl.tewi.jeeunit.junit4.JeeSuite;
import pl.tewi.utils.FileUtils;

/**
 * Automatyczna konfiguracja ścieżki do projektu na podstawie lokalizacji
 * klasy opisanej adnotacją @RunWith(JeeSuite.class)
 * W przypadku maven klasa znajduje się w /target/test-classes
 * @author Marcin Kwapisz
 */
public class RunWithAnnotationProcessor implements AnnotationProcessor {

    private static final String MAVENTARGETTESTCLASSES = "/target/test-classes";

    /**
     * 
     * @param klass klasa opisana adnotacją Junit {@link RunWith}
     * @param context kontekst serwera aplikacji (nie może być null)
     * @return uzupełniony kontekst serwera aplikacji
     * @throws AnnotationProcessingException 
     * @throws GeneralFrameworkException problem z działaniem narzędzia,
     * związany z problemem autokonfiguracji ścieżki bazowej dla projektu
     */
    @Override
    public ApplicationServerContext processAnnotations(final Class<?> klass, final ApplicationServerContext context) throws AnnotationProcessingException, GeneralFrameworkException {
        RunWith runWith = klass.getAnnotation(RunWith.class);
        if (klass != null && runWith.value() == JeeSuite.class) {
            String path = klass.getProtectionDomain().getCodeSource().getLocation().getPath();
            try {
                path = URLDecoder.decode(path, "UTF-8");
                path = removeTargetTestClassesPath(path);
            } catch (UnsupportedEncodingException ex) {
                Logger.getLogger(RunWithAnnotationProcessor.class.getName()).log(Level.SEVERE, null, ex);
                throw new GeneralFrameworkException("Path decoding problem, remove regional characters from project path");
            }
            //sprawdź czy tak utworzony folder istnieje
            if (!FileUtils.isFileExists(path)) {
                throw new FileOrDirectoryException("Project configuration problem");
            }
            context.setProjectPath(path);
            return context;
        } else {
            //Generalnie ta sytuacja nie powinna wystąpić
            throw new GeneralFrameworkException("Class " + klass.getName() + " not anotated with @RunWith(JeeSuite.class)");
        }
    }

    /**
     * 
     * @param path
     * @return 
     */
    private String removeTargetTestClassesPath(final String path) {
        //TODO maven dependant
        String retPath=path;
        if (path.contains(MAVENTARGETTESTCLASSES)) {
            retPath = path.replace(MAVENTARGETTESTCLASSES, "");
        }
        return retPath;
    }
}
